#pragma once
#include <string>
#include <cstring>
#include <jsoncpp/json/json.h>
#define SEP "/r/n"
#define SEPLEN strlen(SEP)
enum{
    DIVZERO=1,
    MODULEZERO,
    UNDIFINE
};

//协议 "textlenth"/r/n"text"
std::string addheader(const std::string& s){
    std::string r;
    std::string textlen = std::to_string(s.size());
    r+=textlen;
    r+=SEP;
    r+=s;
    return r;
}
std::string deleteheader(const std::string&s){
    auto pos =s.find(SEP);
    return s.substr(pos+SEPLEN);
}

class Request{
public:
    Request(const int left = 0,const char oper = 0,const int right = 0)
    :_left(left),_oper(oper),_right(right)
    {}
    
    //序列化
    void serialization(std::string* out){
        Json::Value root;
        root["_left"] = _left;
        root["_oper"] = _oper;
        root["_right"] = _right;
        Json::FastWriter writer;
        *out = writer.write(root);
    }         

    //反序列化
    void unserialization(const std::string& in){
        Json::Value root;
        Json::Reader read;
        read.parse(in,root);
        _left = root["_left"].asInt();
        _oper = root["_oper"].asInt();
        _right = root["_right"].asInt();

    }

public:
    int _left;
    char _oper;
    int _right;
};

class Response{
public:
    Response(const int exitcode = 0,const int result = 0) :_exitcode(exitcode),_result(result)
    {}
    //序列化
    void serialization(std::string* out){
        Json::Value root;
        root["_exitcode"] = _exitcode;
        root["_result"] = _result;
        Json::FastWriter writer;
        *out = writer.write(root);
    }
    //反序列化
    void unserialization(const std::string& in){
        Json::Value root;
        Json::Reader read;
        read.parse(in,root);
        _exitcode = root["_exitcode"].asInt();
        _result = root["_result"].asInt();
    }

public:
    int _exitcode;
    int _result;
};
void handler(const Request& req,Response& res){
    char op = req._oper;
    int left = req._left;
    int right = req._right;
    switch(op){
        case '+':{
            res._result = left + right;
            break;
        }
        case '-':{
            res._result = left - right;
            break;
        }
        case '*':{
            res._result = left * right;
            break;
        }
        case '/':{
            if(right == 0)  res._exitcode = DIVZERO;
            else    res._result = left/right;
            break;
        }
        case '%':{
            if(right == 0)  res._exitcode = MODULEZERO;
            else res._result = left%right;
            break;
        }
        default:{
            res._exitcode = UNDIFINE;
        }

    }
}